package com.zcoj.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zcoj.core.model.PageData;
import com.zcoj.core.model.PageWrap;
import com.zcoj.mapper.ContestMapper;
import com.zcoj.mapper.ContestRegisterMapper;
import com.zcoj.pojo.Dto.*;
import com.zcoj.pojo.Vo.ContestRegisterVO;
import com.zcoj.security.dto.LoginUser;
import com.zcoj.service.*;
import com.zcoj.util.RedisCaches;
import com.zcoj.util.WrapperUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * Service实现
 * @author 剩xia的盛夏
 * @date 2023/02/24 16:16
 */
@Service
@Slf4j
public class ContestServiceImpl implements ContestService {

    @Autowired
    private ContestMapper contestMapper;

    @Autowired
    private RedisCaches redisCaches;

    @Autowired
    private ContestRegisterService contestRegisterService;

    @Autowired
    private ContestRecordService contestRecordService;

    @Autowired
    private ContestProblemService contestProblemService;

    @Autowired
    private ContestAnnouncementService contestAnnouncementService;
    @Autowired
    private ContestRegisterMapper contestRegisterMapper;
    @Override
    public Integer create(Contest contest) {
        System.out.println(contest);
        LoginUser loginUser = redisCaches.getLoginUser();
        contest.setAuthor(loginUser.getUsername());
        contest.setUid(loginUser.getId());
        if(Objects.nonNull(contest.getSealRank())&&contest.getSealRank()==1){
            if(Objects.nonNull(contest.getSealRankTime())){
                if(contest.getSealRankTime().getTime()<contest.getStartTime().getTime()||contest.getSealRankTime().getTime()>contest.getEndTime().getTime()){
                    return 0;
                }
            }else {
                return 0;
            }

        }
        if(Objects.nonNull(contest.getAuth())&&contest.getAuth()==2){
            if(Objects.isNull(contest.getPwd())){
                return 0;
            }
        }
        contestMapper.insert(contest);
        return contest.getId();
    }

    @Override
    public Integer deleteById(Integer id) {
        ContestAnnouncement contestAnnouncement = new ContestAnnouncement();
        contestAnnouncement.setCid(id);
        List<ContestAnnouncement> contestAnnouncements = contestAnnouncementService.findList(contestAnnouncement);
        for (ContestAnnouncement announcement : contestAnnouncements) {
            contestAnnouncementService.deleteById(announcement.getId());
        }

        ContestProblem contestProblem = new ContestProblem();
        contestProblem.setCid(id);
        List<ContestProblem> contestProblemList = contestProblemService.findList(contestProblem);
        for (ContestProblem problem : contestProblemList) {
            contestProblemService.deleteById(problem.getId());
        }

        ContestRegister contestRegister = new ContestRegister();
        contestRegister.setCid(id);
        List<ContestRegister> contestRegisters = contestRegisterService.findList(contestRegister);
        for (ContestRegister register : contestRegisters) {
            contestRegisterService.deleteById(register.getId());
        }

        ContestRecord contestRecord = new ContestRecord();
        contestRecord.setCid(id);
        List<ContestRecord> contestRecords = contestRecordService.findList(contestRecord);
        for (ContestRecord record : contestRecords) {
            contestRecordService.deleteById(record.getId());
        }

        return   contestMapper.deleteById(id);
    }

    @Override
    public void deleteByIdInBatch(List<Integer> ids) {
        if (CollectionUtils.isEmpty(ids)) return;
        contestMapper.deleteBatchIds(ids);
    }

    @Override
    public Integer updateById(Contest contest) {
        return contestMapper.updateById(contest);
    }

    @Override
    public void updateByIdInBatch(List<Contest> contests) {
        if (CollectionUtils.isEmpty(contests)) return;
        for (Contest contest: contests) {
            this.updateById(contest);
        }
    }

    @Override
    public Contest findById(Integer id) {
        return contestMapper.selectById(id);
    }

    @Override
    public Contest findOne(Contest contest) {
        Wrapper<Contest> wrapper = new QueryWrapper<>(contest);
        return contestMapper.selectOne(wrapper);
    }

    @Override
    public List<Contest> findList(Contest contest) {
        Wrapper<Contest> wrapper = new QueryWrapper<>(contest);
        return contestMapper.selectList(wrapper);
    }
  
    @Override
    public PageData<Contest> findPage(PageWrap<Contest> pageWrap) {
        IPage<Contest> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
        Contest contest = WrapperUtil.blankToNull(pageWrap.getModel());
        QueryWrapper<Contest> queryWrapper = new QueryWrapper<>();
        for(PageWrap.SortData sortData: pageWrap.getSorts()) {
            if (sortData.getDirection().equalsIgnoreCase("DESC")) {
                queryWrapper.orderByDesc(sortData.getProperty());
            } else {
                queryWrapper.orderByAsc(sortData.getProperty());
            }
        }
        if(Objects.nonNull(contest.getTitle())){
            queryWrapper.like("title",contest.getTitle());
        }
        if(Objects.nonNull(contest.getVisible())){
            queryWrapper.eq("visible",contest.getVisible());
        }
        if(Objects.nonNull(contest.getAuth())){
            queryWrapper.eq("auth",contest.getAuth());
        }
        queryWrapper.select("id","avatar","author","title","auth","start_time","end_time","visible","create_time","update_time");
        return PageData.from(contestMapper.selectPage(page, queryWrapper));
    }

    @Override
    public PageData<Contest> findPageVo(PageWrap<Contest> pageWrap) {

        LoginUser loginUser = redisCaches.getLoginUser();
        Contest contest = WrapperUtil.blankToNull(pageWrap.getModel());
        IPage<Contest> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());

        QueryWrapper<Contest> queryWrapper = new QueryWrapper<>();
        for(PageWrap.SortData sortData: pageWrap.getSorts()) {
            if (sortData.getDirection().equalsIgnoreCase("DESC")) {
                queryWrapper.orderByDesc(sortData.getProperty());
            } else {
                queryWrapper.orderByAsc(sortData.getProperty());
            }
        }
        if(Objects.nonNull(contest.getTitle())){
            queryWrapper.like("title",contest.getTitle());
        }
        if(Objects.nonNull(contest.getAuth())&&contest.getAuth()!=0){
                queryWrapper.eq("auth",contest.getAuth());
        }
        if(Objects.nonNull(contest.getAuthor())){
            if(!(loginUser.getPermission().contains("admin")||loginUser.getPermission().contains("super_admin")||loginUser.getPermission().contains("contest_admin"))){
                queryWrapper.eq("status",1);
            }
        }
        queryWrapper.select("id","title","type","auth","author","start_time","end_time","avatar");
        IPage<Contest> contestIPage = contestMapper.selectPage(page, queryWrapper);

        return PageData.from(contestIPage);
    }

    @Override
    public Integer checkIsRegister(Integer cid) {
        /**
         1 正常
         2 禁止
         * @author: chen.bin
         * @version: 1.0.0
         * @date 2023/4/10 11:26
         **/
        LoginUser loginUser = redisCaches.getLoginUser();
        QueryWrapper<ContestRegister> contestRegisterQueryWrapper=new QueryWrapper<>();
        contestRegisterQueryWrapper.eq("cid",cid).eq("uid",loginUser.getId());
        ContestRegister contestRegister = contestRegisterMapper.selectOne(contestRegisterQueryWrapper);
        if(Objects.nonNull(contestRegister)){
            if(contestRegister.getStatus()==1){
                return 1;
            }else {
                return 2;//禁用
            }
        }else {

            Contest contest = contestMapper.selectById(cid);
            if(Objects.nonNull(contest)){
                if(contest.getAuth()==1){//1 公开 2私有
                    ContestRegister contestRegister1 = new ContestRegister();
                    contestRegister1.setCid(cid);
                    contestRegister1.setUid(loginUser.getId());
                    contestRegister1.setStatus(1);
                    return contestRegisterMapper.insert(contestRegister1)>0?1:0;
                }

            }
            return 0;
        }
    }

    @Override
    public Integer submitRegister(ContestRegisterVO contestRegisterVO) {
        LoginUser loginUser = redisCaches.getLoginUser();
        log.info("cr{}",contestRegisterVO.toString());
        Contest contest = contestMapper.selectById(contestRegisterVO.getCid());
        if(Objects.nonNull(contest)){
            if(Objects.equals(contest.getPwd(),contestRegisterVO.getPassword())){
                ContestRegister contestRegister = new ContestRegister();
                contestRegister.setStatus(1);
                contestRegister.setCid(contestRegisterVO.getCid());
                contestRegister.setUid(loginUser.getId());
                return contestRegisterMapper.insert(contestRegister)>0?1:0;
            }
        }
        return 0;
    }

    @Override
    public boolean hasOngoingContest() {
        QueryWrapper<Contest> wrapper = new QueryWrapper<>();
        Date date = new Date();
        wrapper.le("start_time", date)
                .ge("end_time", date);
        Integer contestCount= contestMapper.selectCount(wrapper);
        return contestCount>0;
    }

    /**
     * @method: [getContestTime]
     * @param: [cid]
     * @returns: com.zcoj.pojo.Dto.Contest
     * @description:    查询比赛开始结束时间
     * @author: chen.bin
     * @version: 1.0.0
     * @date 2023/8/5 13:04
     **/
    @Override
    public Contest getContestTime(Integer cid) {
        QueryWrapper<Contest> queryWrapper=new QueryWrapper<>();
        queryWrapper.select("id","start_time","end_time");
        queryWrapper.eq("id",cid);
        return contestMapper.selectOne(queryWrapper);
    }

    @Override
    public List<Contest> getContestIdAndTitle() {
        QueryWrapper<Contest> contestQueryWrapper=new QueryWrapper<>();
        contestQueryWrapper.select("id","title");
        return contestMapper.selectList(contestQueryWrapper);
    }

    @Override
    public long count(Contest contest) {
        Wrapper<Contest> wrapper = new QueryWrapper<>(contest);
        return contestMapper.selectCount(wrapper);
    }
}
